package pe.com.bbva.pct.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import pe.com.bbva.pct.dao.ConexionJndiDAO;
import pe.com.bbva.pct.dao.FuenteDAO;
import pe.com.bbva.pct.dao.ReglaFuenteDAO;
import pe.com.bbva.pct.dao.RelacionFuenteEntidadDAO;
import pe.com.bbva.pct.domain.DetalleFuente;
import pe.com.bbva.pct.domain.Fuente;
import pe.com.bbva.pct.domain.ReglaFuente;
import pe.com.bbva.pct.domain.RelacionFuenteEntidad;
import pe.com.bbva.pct.domain.Valor;
import pe.com.bbva.pct.dto.DetalleFuenteDAO;
import pe.com.bbva.pct.dto.DetalleFuenteDTO;
import pe.com.bbva.pct.dto.FuenteDTO;
import pe.com.bbva.pct.service.FuenteService;
import pe.com.bbva.pct.util.ConstantesGenerales;
import pe.com.bbva.pct.vo.FuenteVO;

@Service("fuenteService")
public class FuenteServiceImpl implements FuenteService {

	@Resource(name="fuenteDao")
	private FuenteDAO fuenteDao;
	
	@Resource(name="detalleFuenteDao")
	private DetalleFuenteDAO detalleFuenteDao;
	
	@Resource(name="conexionJndiDao")
	private ConexionJndiDAO conexionJndiDao;
	
	@Resource(name="reglaFuenteDao")
	private ReglaFuenteDAO reglaFuenteDao;
	
	@Resource(name="relacionFuenteEntidadDao")
	private RelacionFuenteEntidadDAO relacionFuenteEntidadDao;
	
	@Transactional(readOnly = true)
	@Override
	public int cantidadTotalObjetos(Object fuenteVO) throws Exception{				
		return fuenteDao.cantidadTotalValores((FuenteVO) fuenteVO);
	}	
	
	
	@Transactional(readOnly = true)
	@Override
	public List<Object> buscarObjetosPaginados(int first, int pageSize, Object fuenteVO) throws Exception{		
		List<Object> listaAplicacionesDTO =new ArrayList<Object>(); 
		List<Fuente> listaFuentesDomain =new ArrayList<Fuente>(); 
		try {
			listaFuentesDomain=fuenteDao.obtenerValoresPaginado(first, pageSize, (FuenteVO) fuenteVO);
			
			Integer intNumeroItem=1;
			for(Fuente fuente:listaFuentesDomain){
				FuenteDTO fuenteDTO=new FuenteDTO();
				fuenteDTO.setIdFuente(fuente.getIdFuente().toString());
				fuenteDTO.setIdTipoFuente(fuente.getIdTipoFuente().getIdValor().toString());
				fuenteDTO.setDescripcionTipoFuente(fuente.getIdTipoFuente().getNombre());
				fuenteDTO.setIdEntradaSalida(fuente.getIdEntradaSalida().getIdValor().toString());
				fuenteDTO.setDescripcionEntradaSalida(fuente.getIdEntradaSalida().getNombre());
				fuenteDTO.setNombre(fuente.getNombre().toString());
				fuenteDTO.setItem(intNumeroItem);
				listaAplicacionesDTO.add(fuenteDTO);
				intNumeroItem++;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return listaAplicacionesDTO;		
	}
	
	@Transactional(readOnly = true)
	@Override
	public FuenteDTO obtenerFuente(Long idFuente) throws Exception{
		FuenteDTO fuenteDTO = new FuenteDTO();
		try {
			Fuente fuente = new Fuente();
			fuente = fuenteDao.obtenerObjeto(idFuente, Fuente.class);
				
				fuenteDTO.setIdFuente(fuente.getIdFuente().toString());
				fuenteDTO.setNombre(fuente.getNombre().toString());
				fuenteDTO.setIdEntradaSalida(fuente.getIdEntradaSalida().getIdValor().toString());
				fuenteDTO.setIdTipoFuente(fuente.getIdTipoFuente().getIdValor().toString());
				fuenteDTO.setIdEstado(fuente.getIdEstado().getIdValor().toString());
				
				if(fuente.getRutaArchivo()==null){
					fuenteDTO.setRutaArchivo(ConstantesGenerales.VALOR_VACIO);
				}else {
					fuenteDTO.setRutaArchivo(fuente.getRutaArchivo().toString());
				}
				
				if(fuente.getConsulta()==null){
					fuenteDTO.setConsulta(ConstantesGenerales.VALOR_VACIO);
				}else {
					fuenteDTO.setConsulta(fuente.getConsulta().toString());
				}
				
				if(fuente.getNombreJndi()==null){
					fuenteDTO.setNombreJdni(ConstantesGenerales.VALOR_VACIO);
				}else {
					fuenteDTO.setNombreJdni(fuente.getNombreJndi().toString());
				}
				
				if(fuente.getNombreTabla()==null){
					fuenteDTO.setNombreTabla(ConstantesGenerales.VALOR_VACIO);
				}else {
					fuenteDTO.setNombreTabla(fuente.getNombreTabla().toString());
				}
				
				if(fuente.getNombreXml()==null){
					fuenteDTO.setNombreXml(ConstantesGenerales.VALOR_VACIO);
				}else {
					fuenteDTO.setNombreXml(fuente.getNombreXml().toString());
				}
				
				if(fuente.getRutaXml()==null){
					fuenteDTO.setRutaXml(ConstantesGenerales.VALOR_VACIO);
				}else {
					fuenteDTO.setRutaXml(fuente.getRutaXml().toString());
				}
			
				List<DetalleFuente> listaDetalleFuente = new ArrayList<DetalleFuente>();
				List<DetalleFuenteDTO> listaDetalleFuenteDTO = new ArrayList<DetalleFuenteDTO>();
				listaDetalleFuente = detalleFuenteDao.obtenerDetalleFuente(fuente.getIdFuente());
					
					Integer Contador=1;
					for(DetalleFuente detalleFuente: listaDetalleFuente){
							DetalleFuenteDTO detalleFuenteDTO = new DetalleFuenteDTO();
							detalleFuenteDTO.setIdDetalleFuente(detalleFuente.getIdDetalleFuente().toString());
							detalleFuenteDTO.setItem(Contador);
							detalleFuenteDTO.setNombreCampo(detalleFuente.getNombreCampo().toString());
							detalleFuenteDTO.setIdTipoDato(detalleFuente.getIdTipoDato().getIdValor().toString());
							detalleFuenteDTO.setIdFuente(detalleFuente.getIdFuente().getIdFuente().toString());
							detalleFuenteDTO.setIdEstado(detalleFuente.getIdEstado().getIdValor().toString());
							
							if(detalleFuente.getInicio() == null){
								detalleFuenteDTO.setInicio(ConstantesGenerales.VALOR_VACIO);
							}else {
								detalleFuenteDTO.setInicio(detalleFuente.getInicio().toString());
							}
							
							if(detalleFuente.getLongitud() == null){
								detalleFuenteDTO.setLongitud(ConstantesGenerales.VALOR_VACIO);
							}else {
								detalleFuenteDTO.setLongitud(detalleFuente.getLongitud().toString());
							}
							
							if(detalleFuente.getFormato() == null){
								detalleFuenteDTO.setFormato(ConstantesGenerales.VALOR_VACIO);
							}else {
								detalleFuenteDTO.setFormato(detalleFuente.getFormato().toString());
							}
							Contador++;
							listaDetalleFuenteDTO.add(detalleFuenteDTO);
					}
		
					fuenteDTO.setListaDetalleFuente(listaDetalleFuenteDTO);
				
		} catch (Exception e) {
			e.printStackTrace();
		}
		return fuenteDTO; 
	}
	
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void eliminarFuente(Long idFuente) throws Exception{
		try {
			
			Fuente fuente = new Fuente();
			fuente=fuenteDao.obtenerObjeto(idFuente, Fuente.class);
			fuente.setIdEstado(new Valor());
			fuente.getIdEstado().setIdValor(ConstantesGenerales.VALOR_ELIMINADO);
			fuenteDao.actualizarObjeto(fuente);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void insertarFuente(FuenteDTO fuenteDTO) throws Exception{
		try {
			Fuente fuente = new Fuente();
			
			fuente.setIdTipoFuente(new Valor());
			fuente.getIdTipoFuente().setIdValor(Long.parseLong(fuenteDTO.getIdTipoFuente()));
			
			fuente.setIdEntradaSalida(new Valor());
			fuente.getIdEntradaSalida().setIdValor(Long.parseLong(fuenteDTO.getIdEntradaSalida()));
			fuente.setIdEstado(new Valor());
			fuente.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
			
			if(fuenteDTO.getNombre()==null){
				fuente.setNombre(ConstantesGenerales.VALOR_VACIO);
			}else {
				fuente.setNombre(fuenteDTO.getNombre().trim());
			}
			
			if(fuenteDTO.getRutaArchivo()==null){
				fuente.setRutaArchivo(ConstantesGenerales.VALOR_VACIO);
			}else {
				fuente.setRutaArchivo(fuenteDTO.getRutaArchivo().trim());
			}
			
			if(fuenteDTO.getConsulta()==null){
				fuente.setConsulta(ConstantesGenerales.VALOR_VACIO);
			}else {
				fuente.setConsulta(fuenteDTO.getConsulta().trim());
			}
			
			if(fuenteDTO.getNombreJdni()==null){
				fuente.setNombreJndi(ConstantesGenerales.VALOR_VACIO);
			}else {
				fuente.setNombreJndi(fuenteDTO.getNombreJdni().trim());
			}
			
			if(fuenteDTO.getNombreTabla()==null){
				fuente.setNombreTabla(ConstantesGenerales.VALOR_VACIO);
			}else {
				fuente.setNombreTabla(fuenteDTO.getNombreTabla().trim());
			}
			if(fuenteDTO.getNombreXml()==null){
				fuente.setNombreXml(ConstantesGenerales.VALOR_VACIO);
			}else {
				fuente.setNombreXml(fuenteDTO.getNombreXml().trim());
			}
			if(fuenteDTO.getRutaXml()==null){
				fuente.setRutaXml(ConstantesGenerales.VALOR_VACIO);
			}else {
				fuente.setRutaXml(fuenteDTO.getRutaXml().trim());
			}
				
			fuente = fuenteDao.insertarObjetoReturnId(fuente);
			//DETALLE DE LA FUENTE
				for(DetalleFuenteDTO ObjetoDTO: fuenteDTO.getListaDetalleFuente()){
						DetalleFuente detalleFuente = new DetalleFuente();
						
						detalleFuente.setIdFuente(new Fuente());
						detalleFuente.getIdFuente().setIdFuente(fuente.getIdFuente());
						
						detalleFuente.setIdTipoDato(new Valor());
						detalleFuente.getIdTipoDato().setIdValor(Long.parseLong(ObjetoDTO.getIdTipoDato()));

						detalleFuente.setIdEstado(new Valor());
						detalleFuente.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
						
						if(ObjetoDTO.getFormato()==null){
							detalleFuente.setFormato(ConstantesGenerales.VALOR_VACIO);
						}else {
							detalleFuente.setFormato(ObjetoDTO.getFormato().trim());
						}
						
						if(ObjetoDTO.getInicio()==null){
							detalleFuente.setInicio(null);
						}else {
							detalleFuente.setInicio(Long.parseLong(ObjetoDTO.getInicio().trim()));
						}
						
						if(ObjetoDTO.getLongitud()==null){
							detalleFuente.setLongitud(null);
						}else {
							detalleFuente.setLongitud(Long.parseLong(ObjetoDTO.getLongitud().trim()));
						}
						
						if(ObjetoDTO.getNombreCampo()==null){
							detalleFuente.setNombreCampo(ConstantesGenerales.VALOR_VACIO);
						}else {
							detalleFuente.setNombreCampo(ObjetoDTO.getNombreCampo().trim());
						}
						
						detalleFuenteDao.insertarObjeto(detalleFuente);
				}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void actualizarFuente(FuenteDTO fuenteDTO) throws Exception{
		try {
			Fuente fuente = new Fuente();
			
			fuente.setIdFuente(Long.parseLong(fuenteDTO.getIdFuente()));
			
			fuente.setIdTipoFuente(new Valor());
			fuente.getIdTipoFuente().setIdValor(Long.parseLong(fuenteDTO.getIdTipoFuente()));
			
			fuente.setIdEntradaSalida(new Valor());
			fuente.getIdEntradaSalida().setIdValor(Long.parseLong(fuenteDTO.getIdEntradaSalida()));
			fuente.setIdEstado(new Valor());
			fuente.getIdEstado().setIdValor(Long.parseLong(fuenteDTO.getIdEstado()));
			
			if(fuenteDTO.getNombre()==null){
				fuente.setNombre(ConstantesGenerales.VALOR_VACIO);
			}else {
				fuente.setNombre(fuenteDTO.getNombre().trim());
			}
			
			if(fuenteDTO.getRutaArchivo()==null){
				fuente.setRutaArchivo(ConstantesGenerales.VALOR_VACIO);
			}else {
				fuente.setRutaArchivo(fuenteDTO.getRutaArchivo().trim());
			}
			
			if(fuenteDTO.getConsulta()==null){
				fuente.setConsulta(ConstantesGenerales.VALOR_VACIO);
			}else {
				fuente.setConsulta(fuenteDTO.getConsulta().trim());
			}
			
			if(fuenteDTO.getNombreJdni()==null){
				fuente.setNombreJndi(ConstantesGenerales.VALOR_VACIO);
			}else {
				fuente.setNombreJndi(fuenteDTO.getNombreJdni().trim());
			}
			
			if(fuenteDTO.getNombreTabla()==null){
				fuente.setNombreTabla(ConstantesGenerales.VALOR_VACIO);
			}else {
				fuente.setNombreTabla(fuenteDTO.getNombreTabla().trim());
			}
			
			if(fuenteDTO.getNombreXml()==null){
				fuente.setNombreXml(ConstantesGenerales.VALOR_VACIO);
			}else {
				fuente.setNombreXml(fuenteDTO.getNombreXml().trim());
			}
			if(fuenteDTO.getRutaXml()==null){
				fuente.setRutaXml(ConstantesGenerales.VALOR_VACIO);
			}else {
				fuente.setRutaXml(fuenteDTO.getRutaXml().trim());
			}
				
			fuente = fuenteDao.actualizarObjeto(fuente);
			//DETALLE DE LA FUENTE
			
//			List<DetalleFuente> listaDetalleFuente = new ArrayList<DetalleFuente>();
//			listaDetalleFuente = detalleFuenteDao.obtenerDetalleFuente(fuente.getIdFuente());
//			for(DetalleFuente detalleFuente: listaDetalleFuente){
//				detalleFuenteDao.borrarObjeto(detalleFuente);
//			}
			
				for(DetalleFuenteDTO ObjetoDTO: fuenteDTO.getListaDetalleFuente()){
						DetalleFuente detalleFuente = new DetalleFuente();
						
						
						detalleFuente.setIdFuente(new Fuente());
						detalleFuente.getIdFuente().setIdFuente(Long.parseLong(fuenteDTO.getIdFuente()));
						detalleFuente.setIdTipoDato(new Valor());
						detalleFuente.getIdTipoDato().setIdValor(Long.parseLong(ObjetoDTO.getIdTipoDato()));
						
						
						
						if(ObjetoDTO.getFormato()==null){
							detalleFuente.setFormato(ConstantesGenerales.VALOR_VACIO);
						}else {
							detalleFuente.setFormato(ObjetoDTO.getFormato().trim());
						}
						
						if(ObjetoDTO.getInicio()==null || ObjetoDTO.getInicio().equals(ConstantesGenerales.VALOR_VACIO)){
							detalleFuente.setInicio(null);
						}else {
							detalleFuente.setInicio(Long.parseLong(ObjetoDTO.getInicio().trim()));
						}
						
						if(ObjetoDTO.getLongitud()==null || ObjetoDTO.getInicio().equals(ConstantesGenerales.VALOR_VACIO)){
							detalleFuente.setLongitud(null);
						}else {
							detalleFuente.setLongitud(Long.parseLong(ObjetoDTO.getLongitud().trim()));
						}
						
						if(ObjetoDTO.getNombreCampo()==null){
							detalleFuente.setNombreCampo(ConstantesGenerales.VALOR_VACIO);
						}else {
							detalleFuente.setNombreCampo(ObjetoDTO.getNombreCampo().trim());
						}
						if(ObjetoDTO.getIdDetalleFuente().equals(ConstantesGenerales.VALOR_VACIO)){
							detalleFuente.setIdEstado(new Valor());
							detalleFuente.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
							detalleFuenteDao.insertarObjeto(detalleFuente);
						}else{
							//detalleFuenteDao.actualizarObjeto(detalleFuente);
							detalleFuente.setIdDetalleFuente(Long.parseLong(ObjetoDTO.getIdDetalleFuente()));
							detalleFuente.setIdEstado(new Valor());
							detalleFuente.getIdEstado().setIdValor(Long.parseLong(ObjetoDTO.getIdEstado()));
							detalleFuenteDao.actualizarObjeto(detalleFuente);
						}
						
				}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Transactional(readOnly = true)
	@Override
	public List<String> obtenerCampos(String jndi, String query, int tipo) throws Exception{
		 List<String> listaCampos = new ArrayList<String>();
		try {
			listaCampos = conexionJndiDao.obtenerCampos(jndi, query, tipo);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return listaCampos;
	}
	
	@Transactional(readOnly = true)
	@Override
	public List<Object[]> obtenerRegistro(String jndi, String query) throws Exception {
	 List<Object[]> listaObjetos = new ArrayList<Object[]>();
		try {
			listaObjetos = conexionJndiDao.obtenerRegistro(jndi, query);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return listaObjetos;
	}
	
	
	public boolean insertarRegistro(List<DetalleFuenteDTO> listaDetalleFuenteDTO, String jndi, String tabla) throws Exception{
		boolean result=false;
		try {
			result = conexionJndiDao.insertarRegistro(listaDetalleFuenteDTO, jndi, tabla);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	@Transactional(readOnly = true)
	@Override
	public Integer validarIntegridadFuente (Long idFuente) throws Exception{
		Integer cantidad=0;
		try {
			List<ReglaFuente> listaReglaFuente = reglaFuenteDao.obtenerReglasPorFuente(idFuente);
			cantidad = listaReglaFuente.size();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return cantidad;
	}
	
	@Transactional(readOnly = true)
	@Override
	public Integer validarIntegridadDetalleFuente(Long idDetalleFuente) throws Exception{
		Integer cantidad=0;
		try {
			List<RelacionFuenteEntidad> listaRelaciones = relacionFuenteEntidadDao.obtenerRelacionesPorDetalleFuente(idDetalleFuente);
			cantidad = listaRelaciones.size();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return cantidad;
	
	}
	
	public ArrayList<HashMap<String, Object>>  ejecutarConsulta(String jndi, String query) throws Exception{
		ArrayList<HashMap<String, Object>>  listaObjetos = new ArrayList<HashMap<String, Object>>() ;
	try {
		listaObjetos = conexionJndiDao.obtenerConsulta(jndi, query);
	} catch (Exception e) {
		e.printStackTrace();
	}
	return listaObjetos;
	}
}
